const request = require('request')
const chalk = require('chalk')
const fs = require('fs')
const options = require('../lc.config')
const { url, prefix } = options.api
// 转换为驼峰
function tf (str) {
    var re = /_(\w)/g;
    return str.replace(re, ($0, $1) =>  $1.toUpperCase())
}
// 生成api文件
function generateFile (globalStr, fetchStr) {
    fs.writeFile(__dirname + '/../src/api/global.js', globalStr, err => {
        if (err) return console.log(`${chalk.bgRed.white(' ERROR ')} ${chalk.red(`写入global失败 ${err}`)}`)
        console.log(`${chalk.bgGreen.black(' SUCCESS ')} ${chalk.cyan('写入global成功')}`)
        console.log()
        fs.writeFile(__dirname + '/../src/api/apiFetch.js', fetchStr, err => {
            if (err) return console.log(`${chalk.bgRed.white(' ERROR ')} ${chalk.red(`写入apiFetch失败 ${err}`)}`)
            console.log(`${chalk.bgGreen.black(' SUCCESS ')} ${chalk.cyan('写入apiFetch成功')}`)
        })
    })
}
// 生成d.ts
function generateDTS (data) {
    let body = `
import Vue from 'vue';
declare module 'vue/types/vue' {
    interface Vue {
        $api: {
${data}
            [propName: string]: any
        }
        [propName: string]: any
    }
}
`
    fs.writeFile(__dirname + '/../src/api.d.ts', body, err => {
        if (err) return console.log(`${chalk.bgRed.white(' ERROR ')} ${chalk.red(`写入api.d.ts失败 ${err}`)}`)
        console.log(`${chalk.bgGreen.black(' SUCCESS ')} ${chalk.cyan('写入api.d.ts成功')}`)
        console.log()
    })
}
function genTypesItem (apiFetch, api, definitions) {
    let str = `\n            ${apiFetch}Fetch(data?): Promise<any>`
    const data = api.parameters.filter(item => !item.name.includes('LC-'))
    const ref = data.length && data[0].schema && data[0].schema.originalRef
    const properties = ref ? definitions[ref].properties : data
    const space = '\n             * '
    let example = Object.keys(properties).map(key => {
        let { name, type, description, items } = properties[key]
        if (items && items.originalRef) {
            const itemProperties = definitions[items.originalRef].properties
            const start =  `------------ ${key} ------------${space}`
            const end = `${space}-----------------------------------------------`
            const itemExample = Object.keys(itemProperties).map(o => {
                const key = o
                const prop = o.padEnd(15, ' ')
                let { type, description } = itemProperties[o]
                type = type ? type.padEnd(15, ' ') : 'binary'
                description = description.trim()
                description = description ? description : key
                return `${prop} | ${type} | ${description}`
            }).join(space)
            return start + itemExample + end
        }
        let prop = (name || key).padEnd(15, ' ')
        type = type ? type.padEnd(15, ' ') : 'binary'
        description = description.replace(name, '').replace(key, '').trim()
        description = description ? description : (name || key)
        return `${prop} | ${type} | ${description}`
    }).join(space)
    example = `            /**${space}${example ? `@example${space}\`\`\`js${space}${example}` : `\`\`\`js${space}无参数`}${space}\`\`\`\n            */${str}\n`
    return example
}
request({ url }, function(err, res, body) {
    console.log(`${chalk.bgCyan.black(' INFO ')} ${chalk.blueBright(`正在读取api文档...`)}`)
    console.log()
    if (err) return console.log(`${chalk.bgRed.white(' ERROR ')} ${chalk.red(`读取api文档失败 ${err}`)}`)
    try {
        let apiList = JSON.parse(body).paths
        let definitions = JSON.parse(body).definitions
        let len = Object.keys(apiList).length
        let globalArr = []
        let fetchArr = []
        let importArr = []
        let curType = ''
        let types = ''
        Object.keys(apiList).forEach((key, index) => {
            const method = Object.keys(apiList[key])[0]
            const api = apiList[key][method]
            const url = key.replace(prefix || '/admin/v1/', '')
            const title = api.summary
            const classify = api.tags[0]
            const data = method === 'get' ? 'params' : 'data'
            const apiURL = url.replace(/\//g, '_').toUpperCase()
            const apiFetch = tf(url.replace(/\//g, '_'))
            const globalItemStr = `export const ${apiURL} = '${url}';// ${title}\n`
            let fetchItemStr = `    ${apiFetch}Fetch: (${data}) => commonPromise({${data}, url: ${apiURL}, method: '${method}'}), // ${title}\n`
            if (index + 1 === len) fetchItemStr = fetchItemStr.replace(', //', ' //')
            if (!curType || curType !== classify) {
                curType = classify
                globalArr.push(`\n// ${curType}\n` + globalItemStr)
                fetchArr.push(`\n    // ${curType}\n` + fetchItemStr)
            } else {
                globalArr.push(globalItemStr)
                fetchArr.push(fetchItemStr)
            }
            importArr.push(apiURL)
            types += genTypesItem(apiFetch, api, definitions) + '\n'
        })
        const globalStr = `/**\n* 全局api\n* 由lc/api.js自动生成\n*/\n${globalArr.join('')}`
        const fetchStr = `import { ${importArr.join(', ')} } from './global.js'\nimport { commonPromise } from '@/http'\nexport default {\n${fetchArr.join('')}\n}\n`
        generateFile(globalStr, fetchStr)
        generateDTS(types)
    } catch (e) {
        console.log(`${chalk.bgRed.white(' ERROR ')} ${chalk.red(`自动生成api文件失败 ${e}`)}`)
    }
})